package com.gitee.l0km.codegen.webclient;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gitee.l0km.codegen.base.Method;
import com.gitee.l0km.com4j.base.Assert;
import com.gitee.l0km.com4j.base.Judge;
import com.gitee.l0km.com4j.base.exception.ServiceRuntimeException;

public class GSoapClient<T> extends WebClient<T> {
	private static final Logger logger = LoggerFactory.getLogger(GSoapClient.class);
	private final String serviceName;

	private final GSoapHeaderHelper gsoapHelper;
	/**
	 * @param interfaceClass
	 * @param refClass
	 * @param serviceClass
	 * @param serviceName
	 * @param stubFolder gsoap stub代码文件夹
	 * @param stubPrefix gsoap stub代码文件前缀
	 */
	public GSoapClient(Class<T> interfaceClass, Class<? extends T> refClass, Class<?> serviceClass, String serviceName,
			File stubFolder, String stubPrefix) {
		super(interfaceClass, refClass, serviceClass);
		Assert.notNull(stubFolder, "stubFolder");
		// stubFolder不是文件夹则抛出异常
		if(!stubFolder.isDirectory())
			throw new IllegalArgumentException(String.format("%s must be a existing directory",stubFolder.getAbsolutePath()));
		this.serviceName = Judge.isEmpty(serviceName) ? serviceClass.getSimpleName() : serviceName;
		this.gsoapHelper=new GSoapHeaderHelper(stubFolder,serviceClass, stubPrefix);
	}

	@Override
	protected void createMethodsNeedGenerated() {
		// 将所有接口中的方法加入methodsNeedGenerated,后续再用removeMethodsNotPort删除不在webservice接口中实现的方法		
		ArrayList<java.lang.reflect.Method> interfaceMethods = new ArrayList<java.lang.reflect.Method>(
				Arrays.asList(interfaceClass.getMethods()));
		try {
			for (Iterator<java.lang.reflect.Method> it = interfaceMethods.iterator(); it.hasNext();) {
				java.lang.reflect.Method im = it.next();
				this.methodsNeedGenerated.add(new Method(refClass.getMethod(im.getName(), im.getParameterTypes()),
						this.paramTable.getParameterNames(im.getName(), im.getParameterTypes())));
			}
		} catch (NoSuchMethodException e) {
			throw new RuntimeException(e);
		}
	}
	/**
	 * 从 methodsNeedGenerated  删除非webservice接口实现方法
	 */
	protected void removeMethodsNotPort() {
		for (Iterator<Method> it = methodsNeedGenerated.iterator(); it.hasNext();) {
			Method im = it.next();
			if(getServicePort(im)==null){
				logger.info("remove method {}",im.getDocSignature());
				it.remove();
			}
		}
	}
	@Override
	public boolean compile() {
		boolean compileOk = false;
		try {
			if (super.compile()) {
				removeMethodsNotPort();
				method2PortMap = createMethod2PortMapMap();
				addImportedClassFromMethods(method2PortMap.values(), true, true, true);
				compileOk = true;
			}
		} catch (NoSuchMethodException e) {
			logger.error(e.toString());
		}
		return compileOk;
	}

	/**
	 * @return serviceName
	 */
	public String getServiceName() {
		return serviceName;
	}

	/**
	 * @return gsoapHelper
	 */
	public GSoapHeaderHelper getGsoapHelper() {
		return gsoapHelper;
	}
	
	public Class<?> getServiceRuntimeClass(){
		return ServiceRuntimeException.class;
	}
}
